mod define_traits;
mod fmt_test;
mod formatter_test;
mod inherit_mut_test;
mod life;
mod myreader;
mod proto_test;
mod secret_num;
mod size_test;
mod struct_test;
mod study_in_half_hour;
mod type_test;
mod type_test2;

use myreader::MyReader;
use rand;
use regex::Regex;
use std::fs::File;
use std::io::{BufReader, Read, Result};
use std::mem;
use std::net::SocketAddr;
use std::rc::Rc;
use std::str::FromStr;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread;
fn main() {
    secret_num::test_secret();
    let _ = 42;
    let x = 3;
    let x = x + 3;
    let tu1 = ("abc", 123);
    let (x1, y1) = tu1;
    // panic!("test invoking");
    println!("x1={:?},y1={:?}", x1, y1);
    println!("tu1.0={:?},tu1.1={:?}", tu1.0, tu1.1);
    println!("x={:?}", x);
    let val = Arc::new(AtomicUsize::new(5));
    for _ in 0..10 {
        let val = Arc::clone(&val);
        thread::spawn(move || {
            let v = val.fetch_add(1, Ordering::SeqCst);
            println!("{:?}", v);
        });
    }

    let f = File::open("/Users/apple/study/rust/practices/ownership/Cargo.toml").unwrap();
    let mut reader = MyReader::new(BufReader::new(f));
    let size = reader.process().unwrap();
    println!("total size read: {}", size);
    let mut str1 = "125.12.88.1118:8088".to_owned();
    let addr1 = String::from(&str1).parse::<SocketAddr>();
    match addr1 {
        Ok(v) => println!("get addr value:{:?}", v),
        Err(err) => println!(
            "parse error:{:?}, wrong addr is:{:?}",
            err.to_string(),
            &str1
        ),
    }

    // let addr=String::from("abc").parse::<SocketAddr>().unwrap();
    let mut strings: Vec<String> = Vec::new();
    for _ in 1..10 {
        if rand::random() {}
    }
    let mut a = "asb dds sdd";
    for i in 0..5 {
        let b = life::strtok(&mut a, " ");
        println!("b={:?}", b);
    }
    life::print_size();
    size_test::test_size();
    if 1 == 1 {
        return;
    }
    println!("{:?}", life::first("aaa bb cc"));
    let data = ["1", "2", "3", "4"];
    let data1 = data;
    // let data2=["1","2","3","4"];
    // println!("{:?}",data);
    println!("sum of data1:{:?}", sum(data1));
    // println!("data1:{:?}", data1);
    // println!("sum of data:{:?}",sum(data));
    println!("data:{:?}", data1); //impl copy trait as element impl Copy in array.
    println!("Hello, world!");
    types_impl_copy_trait();
    types_not_impl_copy_trait();
    copy_semantic_test();
    test_reference();
    brow1_test();
    brow2_test();

    mut_borrow_test();

    mut_borrow_test2();
    mut_borrow_test3();

    mut_addr_test();
    test_used_before_mute();
    test_rc();
    test_rc2();
}
///只读引用实现了 Copy trait，也就意味着引用的赋值、传参都会产生新的浅拷贝
fn test_reference() {
    let data = vec![1, 2, 3, 4];
    let data1 = &data;
    // 值的地址是什么？引用的地址又是什么？
    println!("stack refer addr : data:{:p},data1:{:p}", &data, &data1);
    println!(
        "same heap data addr ,shallow copy: data[0]:{:p},data1[0]:{:p}",
        &data[0], &data1[0]
    );
    println!(
        "addr of value: {:p}({:p}), refer addr of data {:p}, data1: {:p}",
        &&data, data1, &data, &data1
    );
    // println!("sum of data1:{:?}",sum_int(data));
}

fn sum(data: [&str; 4]) -> String {
    data.iter()
        .fold("0".parse().unwrap(), |acc, x| acc.to_owned() + x)
}
fn sum_int(data: [u32; 4]) -> u32 {
    data.iter().fold(0, |acc, x| acc + x)
}

fn is_copy<T: Copy>() {}

fn types_impl_copy_trait() {
    is_copy::<bool>();
    is_copy::<char>();

    // all iXX and uXX, usize/isize, fXX implement Copy trait
    is_copy::<i8>();
    is_copy::<u64>();
    is_copy::<i64>();
    is_copy::<usize>();

    // function (actually a pointer) is Copy
    is_copy::<fn()>();

    // raw pointer is Copy
    is_copy::<*const String>();
    is_copy::<*mut String>();

    // immutable reference is Copy
    is_copy::<&[Vec<u8>]>();
    is_copy::<&String>();

    // array/tuple with values which is Copy is Copy
    is_copy::<[u8; 4]>();
    is_copy::<(&str, &str)>();
}

fn types_not_impl_copy_trait() {
    // unsized or dynamic sized type is not Copy
    // is_copy::<str>();
    // is_copy::<[u8]>();
    // is_copy::<Vec<u8>>();
    // is_copy::<String>();

    // mutable reference is not Copy
    // is_copy::<&mut String>();

    // array / tuple with values that not Copy is not Copy
    // is_copy::<[Vec<u8>; 4]>();
    // is_copy::<(String, u32)>();
}
fn copy_semantic_test() {
    let x = Foo;
    let y = x;
    println!("foo y:{:?}", y);
    println!("foo x:{:?}", x);
    println!("foo x==y:{:?}", &x == &y);
    println!("foo x:{:?}", x);
}
#[derive(Debug, Copy, Clone, PartialEq)]
struct Foo;

fn brow1_test() {
    // let r=local_to_ref();
    // println!("{:?}",r)
}
// fn local_to_ref<'a>()-> &'a i32{
//     let a=4;
//     //returns a reference to data owned by the current function
//     &a
// }

fn brow2_test() {
    let mut data: Vec<&u32> = Vec::new();
    let v = 42;
    data.push(&v);
    // push_local_ref(&mut data);
    println!("brow2_test data: {:?}", data);
}

// fn push_local_ref(data:&mut Vec<&u32>){
//     let v=3;
//     //borrowed value does not live long enough
//     data.push(&v);
// }

///cannot borrow `data` as mutable more than once at a time
/// may lead to data expand to overhead
fn mut_borrow_test() {
    let mut data = vec![1, 2, 3];
    // for item in data.iter_mut() {
    //     data.push(*item + 1);
    // }
    println!("data:{:?}", data)
}

fn mut_borrow_test2() {
    let mut data = vec![1, 2, 3]; //可变数组
                                  // 不可变数组 data1 引用了可变数组 data 中的一个元素，这是个只读引用
    ///如果继续添加元素，堆上的数据预留的空间不够了，就会重新分配一片足够大的内存，把之前的值拷过来，然后释放旧的内存。
    /// 这样就会让 data1 中保存的 &data[0] 引用失效，导致内存安全问题
    let data1 = vec![&data[0]]; //不可变数组
                                // println!("data[0]: {:p}", & data[0]);
                                // for i in 0..100 {
                                //     data.push(i);
                                // }
                                // println!("data[0]: {:p}", &data[0]);
                                // println!("boxed: {:p}", &data1);
}

fn mut_borrow_test3() {
    let mut arr = vec![1, 2, 3];
    // cache the last item
    // let mut last = arr.last();
    arr.push(4);
    // consume previously stored last item
    // println!("last: {:?}", &last);
}

fn extend_vec(v: &mut Vec<i32>) {
    // Vec<T> 堆内存里 T 的个数是指数增长的，我们让它恰好 push 33 个元素
    // capacity 会变成 64
    (2..1 << 11).into_iter().for_each(|i| v.push(i))
}

fn print_vec<T>(name: &str, data: Vec<T>) {
    let p: [usize; 3] = unsafe { mem::transmute(data) };
    //print vec heap addr: addr，capacity，length
    println!(
        "vec name:{:?},vec addr 0x:{:x},vec capacity:{},vec length:{}",
        name, p[0], p[1], p[2]
    )
}

fn mut_addr_test() {
    //capacity is 1 and length is 1
    let mut v = vec![1];
    // print_vec("v",v);
    //capacity is 8,and len is 0
    let v1: Vec<i32> = Vec::with_capacity(8);
    print_vec("v1", v1);
    // 我们先打印 heap 地址，然后看看添加内容是否会导致堆重分配
    //heap start index 0:0x7fd6b1405a70
    println!("heap start index 0:{:p}", &v[0] as *const i32);
    extend_vec(&mut v);
    //    heap start index 0 ,after expend:0x7fd6b1405a70
    println!("heap start index 0 ,after expend:{:p}", &v[0] as *const i32);
    //vec name:"v",vec addr 0x:7fd6b1405a70,vec capacity:64,vec length:33
    let v2 = v.clone();
    print_vec("v", v);
    print_vec("clone v", v2);
    // println!("v:{:?}",v.clone())
}

fn test_used_before_mute() {
    let mut arr = vec![1, 2, 3];
    // cache the last item
    let last = arr.last();
    // consume previously stored last item
    println!("last: {:?}", last);
    arr.push(4);
    let o = Option::Some("asdf");
    println!("{:?}", o);
    let o1: Option<&str> = Option::None;
    println!("o1:{:p}", &o1);
    println!("o1:{:p}", &o1)
}

fn test_rc() {
    let rc1 = Rc::new("a");
    let rc11 = rc1.clone();
    println!("rc1 addr:{:p}", rc1);
    println!("rc11 addr:{:p}", rc11);

    println!("rc1 stack addr:{:p}", &rc1);
    println!("rc11 stack addr:{:p}", &rc11);

    println!("rc1 pointer addr:{:p}", *rc1);
    println!("rc11 pointer addr:{:p}", *rc11);
}

fn test_rc2() {
    let rc1 = Rc::new(1);
    let rc11 = rc1.clone();
    println!("rc1 addr:{:p}", rc1);
    println!("rc11 addr:{:p}", rc11);

    println!("rc1 stack addr:{:p}", &rc1);
    println!("rc11 stack addr:{:p}", &rc11);
    //the trait `Pointer` is not implemented for `{integer}`
    // println!("rc1 pointer addr:{:p}",*rc1);
    // println!("rc11 pointer addr:{:p}",*rc11);
}
#[test]
fn test_reference_mut_same() {
    let mut v = vec![1, 2, 3, 4, 5];
    let first = &v[0]; //immutable borrow occurs here.
                       // v.push(6); /// mutable borrow occurs here
    println!("The first element is: {}", first);
}
#[test]
fn test_hash_map() {
    use std::collections::HashMap;
    let field_name = String::from("favorite color");
    let field_value = String::from("blue");
    let mut map = HashMap::new();
    map.insert(field_name, field_value);
    // println!("field name:{:?}",field_name); field_name owned type has not implement Copy. so ownership moved to map.
    println!("field name:{:?}", map);
    map.insert(String::from("Blue"), "10".to_owned());
    map.entry(String::from("Yellow"))
        .or_insert("100".to_owned());
    map.entry(String::from("Blue")).or_insert("100".to_owned()); //exists then not update. otherwise set new value.
    println!("field name:{:?}", map);
}

#[test]
fn test_impl_3rd_place() {
    let a = life::S1::new();
    println!("{:?}", a);
}

impl life::S1 {
    pub fn new() -> life::S1 {
        life::S1 {
            a: 12,
            b: 123,
            c: 123,
        }
    }
}
fn rc_is_not_sync_send() {
    ///the trait `Send` is not implemented for `Rc<i32>`
    let a = Rc::new(1);
    let b = a.clone();
    let c = b.clone();
    // thread::spawn(move ||{
    //     println!("c:{:?}",c);
    // });
}
